package com.app.service.Impl;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.app.mapper.GasDetailsMapper;
import com.app.mapper.RequestLogsMapper;
import com.app.pojo.GasDetails;
import com.app.pojo.RequestLogs;
import com.app.service.IRequestLogsService;
import com.app.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;

/**
 * <p>
 * 请求日志记录表 服务实现类
 * </p>
 *
 * @author yoominic
 * @since 2024-08-01
 */
@Service
public class RequestLogsServiceImpl extends ServiceImpl<RequestLogsMapper, RequestLogs> implements IRequestLogsService {

    @Value("${gas.api.url}")
    private String GAS_API_URL;
    @Value("${gas.api.key}")
    private String GAS_API_KEY;


    @Autowired
    private RequestLogsMapper requestLogsMapper;

    @Autowired
    private GasDetailsMapper gasDetailsMapper;

    @Autowired
    private Md5Util md5Util;

    @Autowired
    private HttpRequestUtil httpRequestUtil;


    @Override
    public JSONObject receiveGasRequestLogs(JSONObject jonstr,String ip) {
        long startTime = System.nanoTime(); // 记录开始时间
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.setRequestMessage(jonstr.toJSONString());
        requestLogs.setCreatedAt(LocalDateTime.now());

//        long endTime = System.nanoTime(); // 记录结束时间
//        long durationNanos = endTime - startTime; // 计算时间差（纳秒）
//        int durationMillis = (int) (durationNanos / 1_000_000); // 转换为毫秒并强制转换为int
        requestLogs.setType("燃气推送我方接收日志");
        requestLogs.setIpAddress(ip);
//        requestLogs.setDuration(durationMillis);
        requestLogs.setMeterno(jonstr.getString("meterno"));
        requestLogsMapper.insert(requestLogs);

        JSONObject response_object = new JSONObject();


        //3003返回 应该有的客户余额情况
        if ("3003".equals(jonstr.getString("code"))){
            QueryWrapper<GasDetails> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("gas_number", jonstr.getString("meterno"));
            queryWrapper.last("LIMIT 1");
            GasDetails gasDetails = gasDetailsMapper.selectOne(queryWrapper);
            String gasNumber = "";
            String str_000F = "000";//当前余额（1 元=100）
            String str_000D = "00000";//单价（1 元=10000）
            String str_0018 = "0";//总购量
            if (null != gasDetails){
                gasNumber = gasDetails.getGasNumber();

                //同步表时间
//                LocalDateTime now = LocalDateTime.now();
//                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d HH:mm:ss");
//                String formattedDateTime = now.format(formatter);
//                pushGasRequestLogs("0002",gasNumber, formattedDateTime);

                //还需要发送多天不上报关闸控制指令 value为天数
//                pushGasRequestLogs("2010",gasNumber, "2");

                //数据库中的单价
                BigDecimal unitPrice = gasDetails.getUnitPrice();
                //数据库中的余额
                BigDecimal old_balance = gasDetails.getBalance();

                //从接收报文中获取最新总气量
                String new_gas_meter_total = jonstr.getJSONObject("data").getString("0003");

                System.err.println("从接收报文中获取最新总气量 = " + new_gas_meter_total);


                //数据库中记录的当前总气量
                BigDecimal old_gasMeterTotal = gasDetails.getGasMeterTotal();
                // 计算总气量差值 （报文最新返回的气量 - 数据库中记录的气量）
                BigDecimal difference =  new BigDecimal(new_gas_meter_total).subtract(old_gasMeterTotal);

                //如果气量差值不为0 则需要扣减余额
                if (difference.compareTo(BigDecimal.ZERO) != 0){

                    //本次需要扣减的金额 (气量差值 / 单价)
                    BigDecimal amount_difference = difference.divide(unitPrice, 10, RoundingMode.HALF_UP);
                    // 计算扣减后的余额 （数据库中的余额 - 本次需要扣减的金额）
                    BigDecimal new_balance = old_balance.subtract(amount_difference);
                    //计算剩余燃气量 （新的余额 * 单价）
                    BigDecimal new_gasMeterBalance = new_balance.multiply(unitPrice);

                    // 余额小于0 下发关闸指令
                    if (new_balance.compareTo(BigDecimal.ZERO) < 0) {
                        pushGasRequestLogs("0001",gasNumber, "1");
                    }


                    //当前余额（1 元=100）
                    str_000F = new_balance.multiply(new BigDecimal("100")).toString();
                    //单价（1 元=10000）
                    str_000D = unitPrice.multiply(new BigDecimal("1000")).toString();
                    // 执行除法操作  计算当前剩余气量
                    BigDecimal result = new BigDecimal(str_000F).divide(new BigDecimal(str_000D), 10, RoundingMode.HALF_UP);
                    str_0018 = result.toString();

                    //更新数据库中的总气量
                    if (StringUtils.isNotEmpty(new_gas_meter_total)){
                        gasDetails.setGasMeterTotal(new BigDecimal(new_gas_meter_total));
                    }else {
                        gasDetails.setGasMeterTotal(new BigDecimal("0"));
                    }


                    //更新数据库中的余额
                    gasDetails.setBalance(new_balance);
                    //更新数据库中的剩余气量
                    gasDetails.setGasMeterBalance(new_gasMeterBalance);
                    //更新数据库中的上报日期
                    gasDetails.setCommunicationRecordDate(LocalDateTime.now());
                    gasDetailsMapper.updateById(gasDetails);
                }


                str_000F = gasDetails.getBalance().multiply(new BigDecimal("100")).toString();

                str_000D = gasDetails.getUnitPrice().multiply(new BigDecimal("10000")).toString();

                str_0018 = gasDetails.getTotalPurchaseAmount().multiply(new BigDecimal("100")).toString();

            }else {
                gasNumber = jonstr.getString("meterno");
            }
            response_object.put("meterno", gasNumber);
            response_object.put("000F", str_000F);
            response_object.put("000D", str_000D);
            response_object.put("0018", str_0018);

            String signature = md5Util.generateMD5( gasNumber + GAS_API_KEY);
            response_object.put("signature", signature);

            requestLogs.setMeterno(gasNumber);
            requestLogs.setCode(jonstr.getString("code"));
            requestLogs.setResponseMessage(response_object.toJSONString());
            requestLogsMapper.insert(requestLogs);
            return response_object;
        }else if ("3001".equals(jonstr.getString("code"))){
            //燃气平台说   3001我方不用处理 返回一个ok之类的就可以  总之不报错就行
            response_object.put("code", "200");
            response_object.put("message", "OK");
            requestLogsMapper.insert(requestLogs);
            requestLogs.setResponseMessage(response_object.toJSONString());
            return response_object;
        }

        response_object.put("code", "200");
        response_object.put("message", "OK");
        requestLogs.setMeterno(jonstr.getString("meterno"));
        requestLogs.setResponseMessage(response_object.toJSONString());
        requestLogsMapper.insert(requestLogs);
        return response_object;

    }


    @Override
    public JSONObject pushGasRequestLogs(String field,String meterno,String value) {

        long startTime = System.nanoTime(); // 记录开始时间

        String signature = md5Util.generateMD5(  field +  meterno + value + GAS_API_KEY);
        JSONObject parm = new JSONObject();
        parm.put("field", field);
        parm.put("meterno", meterno);
        parm.put("value", value);
        parm.put("signature", signature);
        JSONObject jsonObject = httpRequestUtil.httpRequest(GAS_API_URL, EnumMethod.POST.name(),parm.toJSONString());
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.setType("我方推送到燃气平台");
        requestLogs.setRequestMessage(parm.toJSONString());
        requestLogs.setCreatedAt(LocalDateTime.now());
        requestLogs.setCode(field);
        requestLogs.setMeterno(meterno);
        long endTime = System.nanoTime(); // 记录结束时间
        long durationNanos = endTime - startTime; // 计算时间差（纳秒）
        int durationMillis = (int) (durationNanos / 1_000_000); // 转换为毫秒并强制转换为int

        requestLogs.setType("我方推送到燃气平台");
        requestLogs.setDuration(durationMillis);
        requestLogs.setResponseMessage(jsonObject.toJSONString());

        // 保存日志
        requestLogsMapper.insert(requestLogs);

        return jsonObject;
    }

    /**
     * 给燃气发请求，查余额
     * @param meterno
     * @return
     */
    @Override
    public BigDecimal checkBalance( String meterno) {
        long startTime = System.nanoTime(); // 记录开始时间
        String field = "0008";//查询余额的指令代号
        String signature = md5Util.generateMD5(  field +  meterno + "" + GAS_API_KEY);
        JSONObject parm = new JSONObject();
        parm.put("field", field);
        parm.put("meterno", meterno);
        parm.put("signature", signature);
        JSONObject jsonObject = httpRequestUtil.httpRequest(GAS_API_URL, EnumMethod.POST.name(),parm.toJSONString());
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.setType("我方推送到燃气平台——查燃气表余额");
        requestLogs.setRequestMessage(parm.toJSONString());
        requestLogs.setCreatedAt(LocalDateTime.now());
        requestLogs.setCode(field);
        requestLogs.setMeterno(meterno);
        long endTime = System.nanoTime(); // 记录结束时间
        long durationNanos = endTime - startTime; // 计算时间差（纳秒）
        int durationMillis = (int) (durationNanos / 1_000_000); // 转换为毫秒并强制转换为int
        requestLogs.setDuration(durationMillis);
        requestLogs.setResponseMessage(jsonObject.toJSONString());
        // 保存日志
        requestLogsMapper.insert(requestLogs);
        //从返回值里面拿到燃气表余额
        BigDecimal balance = new BigDecimal("0");//余额
        return balance;
    }


//    /**
//     * 查一个户号的余额
//     */
//    @Override
//    public JSONObject checkBalance(String field,String meterno,String value) {
//        long startTime = System.nanoTime();
//    }



}
